package com.tech.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Sheet;
import lombok.Data;
import com.tech.model.DocModelField;
import static com.tech.utils.Option.*;

import java.util.*;

/**
 * Created by zouyao on 2023/06/02
 */
@Data
public class DocModelFieldListener extends AnalysisEventListener<DocModelField> {

    private boolean inFlag = false;
    private String                                                        currentSheetInfo ;
    private Map<String/**sheetInfo*/, List<DocModelField>/**fieldInfo*/ > docInfoArena = new HashMap<>();

    @Override
    public void invoke(DocModelField field, AnalysisContext analysisContext) {
        Sheet currentSheet = analysisContext.getCurrentSheet();
        currentSheetInfo =  currentSheet.getSheetName();

        if (StrUtil.equals(field.getIndex(), IN)){
            inFlag = true;
            return;
        }
        if (StrUtil.equals(field.getIndex(), OUT)){
            inFlag = false;
            return;
        }
        field.setDataFlow(getDataFlow());

        if (StrUtil.equals(field.getType(), "ARRAY")){
            field.setType("List<" + field.getClassName() + ">");
        }

        if (!field.getIndex().contains(".")) {
            field.setParentIndex("0");
        }else {
            String[] arr = field.getIndex().split("\\.");
            String[] newArr = Arrays.copyOfRange(arr, 0, arr.length - 1);
            String parentIndex = String.join(".", newArr);
            field.setParentIndex(parentIndex);
        }
        putField(field);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {}

    private void putField(DocModelField field){
        if ( Objects.isNull( docInfoArena.get(currentSheetInfo) )){
            docInfoArena.put(currentSheetInfo,new ArrayList<>());
        }
        docInfoArena.get(currentSheetInfo).add(field);
    }

    private String getDataFlow(){
        return inFlag?IN:OUT;
    }

}
